package com.candy.biz.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.candy.biz.domain.param.SysDeptQueryParam;
import com.candy.biz.domain.param.SysDeptSaveParam;
import com.candy.biz.domain.vo.SysDeptVO;
import com.candy.biz.manager.SysDeptManager;
import com.candy.common.constant.CommonConstant;
import com.candy.common.domain.PageVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.If;
import com.candy.biz.domain.entity.SysDept;
import com.candy.biz.mapper.SysDeptMapper;
import com.candy.biz.service.SysDeptService;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.candy.common.utils.CommonUtil;
import java.util.List;
import java.util.Optional;

import lombok.SneakyThrows;
import cn.hutool.core.lang.tree.Tree;
import static com.candy.biz.domain.entity.table.SysDeptTableDef.SYS_DEPT;

/**
 * 部门-服务层实现。
 *
 * @author rong xi
 * @date 2023/10/26 13:33
 * @version 1.0.0
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    /**
     * 查询部门详情
     *
     * @param id 部门id
     * @return 详情VO
     */
    @Override
    public SysDeptVO queryInfo(Long id) {
        return this.getByIdOpt(id).map(SysDeptManager::poToVo).orElse(null);
    }

    /**
     * 分页查询部门
     *
     * @param param 查询参数
     * @return 分页结果
     */
    @Override
    public PageVO<SysDeptVO> queryPage(SysDeptQueryParam param) {
        Page<SysDept> page = queryChain()
                .select(SYS_DEPT.ALL_COLUMNS)
                .from(SYS_DEPT)
                .where(SYS_DEPT.ID.eq(param.getId(), If::notNull))
                .and(SYS_DEPT.DEPT_NAME.like(param.getDeptName(), If::hasText))
                .and(SYS_DEPT.PARENT_ID.eq(param.getParentId(), If::notNull))
                .orderBy(param.getOrderBy(SYS_DEPT))
                .page(param.getPage());
        return SysDeptManager.pageToPageVO(page);
    }


    /**
     * 根据条件查询部门树集合。
     *
     * @param param 查询参数
     * @return 查询结果
     */
    @Override
    public List<Tree<Long>> queryTreeList(SysDeptQueryParam param){
        List<SysDept> list = queryChain()
                .select(SYS_DEPT.ALL_COLUMNS)
                .from(SYS_DEPT)
                .where(SYS_DEPT.ID.eq(param.getId(), If::notNull))
                .and(SYS_DEPT.DEPT_NAME.like(param.getDeptName(), If::hasText))
                .and(SYS_DEPT.PARENT_ID.eq(param.getParentId(), If::notNull))
                .orderBy(param.getOrderBy(SYS_DEPT))
                .list();
        Long rootId = Optional.ofNullable(param.getParentId()).orElse(Long.valueOf(CommonConstant.NO));
        return SysDeptManager.posToTreeList(list,rootId);
    }

    /**
     * 根据条件查询部门树。
     *
     * @param param 查询参数
     * @return 查询结果
     */
    @Override
    public Tree<Long> queryTree(SysDeptQueryParam param){
        List<SysDept> list = queryChain()
                .select(SYS_DEPT.ALL_COLUMNS)
                .from(SYS_DEPT)
                .where(SYS_DEPT.ID.eq(param.getId(), If::notNull))
                .and(SYS_DEPT.DEPT_NAME.like(param.getDeptName(), If::hasText))
                .and(SYS_DEPT.PARENT_ID.eq(param.getParentId(), If::notNull))
                .orderBy(param.getOrderBy(SYS_DEPT))
                .list();
        Long rootId = Optional.ofNullable(param.getParentId()).orElse(Long.valueOf(CommonConstant.NO));
        return SysDeptManager.posToTree(list,rootId);
    }

    /**
     * 根据查询条件导出部门。
     *
     * @param param 查询条件
     */
    @Override
    @SneakyThrows
    public void export(SysDeptQueryParam param) {
        //修改分页条件
        param.preparationExport();
        //查询数据
        List<SysDeptVO> rows = queryPage(param).getList();
        //导出文件
        CommonUtil.exportExcel("部门",rows,SysDeptVO.class);
    }


    /**
     * 保存部门
     *
     * @param param 保存参数
     * @return 保存结果
     */
    @Override
    public Boolean saveHandle(SysDeptSaveParam param) {
        return CommonUtil.<SysDeptSaveParam,Boolean>predicateFunction(param,
                (p)-> ObjectUtil.isNull(p.getId()),
                //新增
                (p)->this.save(SysDeptManager.insertPrepare(p)),
                //修改
                (p)-> this.updateById(SysDeptManager.updatePrepare(p)));
    }
}
